package marketPlace;

import general.ProductRecord;

import java.rmi.Remote;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.UUID;

import net.jini.core.lookup.ServiceID;
import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceTemplate;
import net.jini.core.transaction.server.TransactionManager;
import net.jini.discovery.LookupDiscoveryManager;
import net.jini.export.Exporter;
import net.jini.jeri.BasicILFactory;
import net.jini.jeri.BasicJeriExporter;
import net.jini.jeri.tcp.TcpServerEndpoint;
import net.jini.lease.LeaseRenewalManager;
import net.jini.lookup.JoinManager;
import net.jini.lookup.ServiceDiscoveryManager;
import net.jini.lookup.ServiceIDListener;
import net.jini.space.JavaSpace;

public class MarketPlace implements ServiceIDListener {
	
	private MarketPlaceMarketeerService fMarketPlaceMarketeerService;
	private HashMap<UUID, ProductRecord> fProductRecords;
	private AuctionQueue fAuctionQueue;
	
	public MarketPlace() {
		
		fProductRecords = new HashMap<UUID, ProductRecord>();
		fAuctionQueue = new AuctionQueue(this);
		
		try {
			
			// Construct exporter for MarketPlace class
			Exporter exporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0), new BasicILFactory());
			fMarketPlaceMarketeerService = new MarketPlaceMarketeerService(this);
			Remote proxy = exporter.export(fMarketPlaceMarketeerService);
		
			// Register service
			LookupDiscoveryManager discoveryMgr = new LookupDiscoveryManager(new String [] {"JORSEBREGGIE"}, null, null);
			JoinManager joinMgr = new JoinManager(proxy, null, this, discoveryMgr, new LeaseRenewalManager());

		} catch (Exception e) {
			e.printStackTrace();
		}
	
		// Output
		System.out.println("MarketPlace started...");
	}

	public void serviceIDNotify(ServiceID serviceID) {
		System.out.println("Service registered with service ID " + serviceID.toString());
	}
	
	public void addProductRecord(ProductRecord productRecord) {
		fProductRecords.put(productRecord.getProduct().getId(), productRecord);
	}
	
	public LinkedList<ProductRecord> searchProducts(String name) {
		// Create result list
		LinkedList<ProductRecord> resultList = new LinkedList<ProductRecord>();
		
		// Search for products which match the conditions
		Iterator<ProductRecord> records = fProductRecords.values().iterator();
		while (records.hasNext()) {
			ProductRecord record = records.next();
			if (record.getProduct().getName().indexOf(name) >= 0) {
				resultList.add(record);
				System.out.println("Ja");
			} else {
				System.out.println("Nee");
			}
		}
		
		// Return result
		return resultList;
	}
	
	public void addToAuctionQueue(ProductRecord productRecord) {
		fAuctionQueue.addProductRecord(productRecord);
	}
	
	public JavaSpace getSpace() {
		
		JavaSpace space = null;
		
		try {
			// Get lookup service
			LookupDiscoveryManager discoveryMgr = new LookupDiscoveryManager(new String [] {"JORSEBREGGIE"}, null, null);
			ServiceDiscoveryManager serviceMgr = new ServiceDiscoveryManager(discoveryMgr, new LeaseRenewalManager());

			// Search for MarketeteerClient service
			Class[] classes = new Class[] { JavaSpace.class }; 
			ServiceTemplate template = new ServiceTemplate(null, classes, null);
			ServiceItem item = null;
			item = serviceMgr.lookup(template, null, 1000L);

			// Get the service
			if (item == null) {
				System.out.println("Space not found"); 
				System.exit(1);
			}
			space = (JavaSpace) item.service;
			if (space == null) { 
				System.out.println("Space not found"); 
				System.exit(1);
			}
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return space;
		
	}
	
	public TransactionManager getTransactionManager() {
		
		TransactionManager transactionMgr = null;
		
		try {
			// Get lookup service
			LookupDiscoveryManager discoveryMgr = new LookupDiscoveryManager(new String [] {"JORSEBREGGIE"}, null, null);
			ServiceDiscoveryManager serviceMgr = new ServiceDiscoveryManager(discoveryMgr, new LeaseRenewalManager());

			// Search for MarketeteerClient service
			Class[] classes = new Class[] { TransactionManager.class }; 
			ServiceTemplate template = new ServiceTemplate(null, classes, null);
			ServiceItem item = null;
			item = serviceMgr.lookup(template, null, 1000L);

			// Get the service
			if (item == null) {
				System.out.println("TransactionManager not found"); 
				System.exit(1);
			}
			transactionMgr = (TransactionManager) item.service;
			if (transactionMgr == null) { 
				System.out.println("TransactionManager not found"); 
				System.exit(1);
			}
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return transactionMgr;
		
	}

}
